package com.iteaj.iot.client.component;

import com.iteaj.iot.client.SocketClient;
import com.iteaj.iot.*;
import com.iteaj.iot.client.ClientComponent;
import com.iteaj.iot.client.ClientMessage;
import com.iteaj.iot.client.IotClient;
import com.iteaj.iot.client.MultiClientManager;
import com.iteaj.iot.config.ConnectProperties;
import org.springframework.beans.factory.InitializingBean;

import java.util.Collection;

/**
 * 基于socket的客户端组件 主要tcp, upd等
 * @param <M>
 */
public abstract class SocketClientComponent<M extends ClientMessage> extends ProtocolFactory<M> implements ClientComponent<M>, IotProtocolFactory<M>, InitializingBean {

    private IotClient iotClient;
    private ConnectProperties config;
    private MultiClientManager clientManager;

    public SocketClientComponent(ConnectProperties config) {
        this(config, new SimpleMultiClientManager(null));
    }

    public SocketClientComponent(ConnectProperties config, MultiClientManager clientManager) {
        this.config = config;
        this.clientManager = clientManager;
        this.setDelegation(new ProtocolTimeoutStorage(this.getDesc()));

        if(this.clientManager.getClientComponent() == null) {
            this.clientManager.setClientComponent(this);
        }
    }

    @Override
    public void init(Object ...args) {
        this.getClient().init(args[0]);
    }

    @Override
    public void connect() {
        this.getClient().connect(null, 3000);
    }

    @Override
    public void addClient(Object clientKey, IotClient value) {
        this.clientManager.addClient(clientKey, value);
    }

    @Override
    public IotClient getClient() {
        if(this.iotClient != null) {
            return this.iotClient;
        } else {
            return this.iotClient = createNewClient(this.config);
        }
    }

    @Override
    public Collection<IotClient> clients() {
        return clientManager.clients();
    }

    @Override
    public IotClient getClient(Object clientKey) {
        return clientManager.getClient(clientKey);
    }

    @Override
    public IotClient removeClient(Object clientKey) {
        return clientManager.removeClient(clientKey);
    }

    @Override
    public void setClientComponent(ClientComponent component) {
        this.clientManager.setClientComponent(component);
    }

    /**
     * 创建一个新客户端
     * @param config
     * @return
     */
    public abstract SocketClient createNewClient(ConnectProperties config);

    @Override
    public IotProtocolFactory protocolFactory() {
        return this;
    }

    public MultiClientManager getClientManager() {
        return clientManager;
    }

    protected ProtocolTimeoutStorage createProtocolTimeoutStorage() {
        return new ProtocolTimeoutStorage(getName());
    }

    /**
     * 短线重连时间间隔(秒)
     * @return
     */
    public long getReconnectTime() {
        return getConfig().getReconnect();
    }

    public ConnectProperties getConfig() {
        return config;
    }

    public void setConfig(ConnectProperties config) {
        this.config = config;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        getClient();
        protocolFactory();
    }
}
